6.2.10 镜像和分层

Docker镜像由一些松耦合的只读镜像层组成。如图6.3所示。

25.png

图6.3 Docker镜像

Docker负责堆叠这些镜像层,并且将它们表示为单个统一的对象。

有多种方式可以查看和检查构成某个镜像的分层,本书在前面已经展示了其中一种。接下来再回顾一下 docker image pull ubuntu:latest 命令的输出内容。

$ docker image pull ubuntu:latest
latest: Pulling from library/ubuntu
952132ac251a: Pull  complete
82659f8f1b76: Pull  complete
c19118ca682d: Pull  complete
8296858250fe: Pull  complete
24e0251a0e2c: Pull complete
Digest: sha256:f4691c96e6bbaa99d...28ae95a60369c506dd6e6f6ab
Status: Downloaded newer image for ubuntu:latest

在上面输出内容中,以 Pull complete 结尾的每一行都代表了镜像中某个被拉取的镜像层。可以看到,这个镜像包含5个镜像层。图6.4以图片形式将镜像层ID作为标识展示了这些分层。

26.png

图6.4 镜像层

另一种查看镜像分层的方式是通过 docker image inspect 命令。下面同样以 ubuntu:latest 镜像为例。

$ docker image inspect ubuntu:latest
[
    {
       "Id": "sha256:bd3d4369ae.......fa2645f5699037d7d8c6b415a10",
       "RepoTags": [
           "ubuntu:latest"
       <Snip>
       "RootFS": {
           "Type": "layers",
           "Layers": [
               "sha256:c8a75145fc...894129005e461a43875a094b93412",
               "sha256:c6f2b330b6...7214ed6aac305dd03f70b95cdc610",
               "sha256:055757a193...3a9565d78962c7f368d5ac5984998",
               "sha256:4837348061...12695f548406ea77feb5074e195e3",
               "sha256:0cad5e07ba...4bae4cfc66b376265e16c32a0aae9"
           ]
       }
    }
]

缩减之后的输出也显示该镜像包含5个镜像层。只不过这次的输出内容中使用了镜像的SHA256散列值来标识镜像层。不过,两中命令都显示了镜像包含5个镜像层。

注:

docker history 命令显示了镜像的构建历史记录,但其并不是严格意义上的镜像分层。例如,有些Dockerfile中的指令并不会创建新的镜像层。比如ENV、EXPOSE、CMD以及ENTRY- POINT。不过,这些命令会在镜像中添加元数据。

所有的Docker镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上,创建新的镜像层。

举一个简单的例子,假如基于Ubuntu Linux 16.04创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加Python包,就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创建第三个镜像层。该镜像当前已经包含3个镜像层,如图6.5所示(这只是一个用于演示的很简单的例子)。

27.png

图6.5 基于Ubuntu Linux 16.04创建镜像

在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要。图6.6中举了一个简单的例子,每个镜像层包含3个文件,而镜像包含了来自两个镜像层的6个文件。

28.png

图6.6 添加额外的镜像层后的镜像

注:

图6.6中的镜像层跟之前图中的略有区别,主要目的是便于展示文件。

图6.7中展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有6个文件,这是因为最上层中的文件7是文件5的一个更新版本。这种情况下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中。

29.png

图6.7 三层镜像

Docker通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统。Linux上可用的存储引擎有 AUFSOverlay2Device MapperBtrfs 以及 ZFS 。顾名思义,每种存储引擎都基于Linux中对应的文件系统或者块设备技术,并且每种存储引擎都有其独有的性能特点。Docker在Windows上仅支持 windowsfilter 一种存储引擎,该引擎基于NTFS文件系统之上实现了分层和CoW[1]

图6.8展示了与系统显示相同的三层镜像。所有镜像层堆叠并合并,对外提供统一的视图。

30.png

图6.8 从系统角度看三层镜像

results matching ""

    No results matching ""